CORS设置跨域不生效排查之路

您所在的位置:网站首页 beego web 过滤器不生效 CORS设置跨域不生效排查之路

CORS设置跨域不生效排查之路

2023-12-29 11:47| 来源: 网络整理| 查看: 265

结构:springboot2.x版本

CORS(跨域资源共享),可以把其当做是通过设置http响应头来允许不同协议、ip、port可以跨域请求。

在springboot中,一般常采用两种方式实现CORS:

一,通过拦截器的方式,通过继承WebMvcConfigurationSupport,重写addCorsMappings方法,具体代码如下:

    @Override     protected void addCorsMappings(CorsRegistry registry) {         registry.addMapping("/**")         .allowCredentials(true)         .allowedHeaders("*")         .allowedMethods("*")         .allowedOrigins("*");         super.addCorsMappings(registry);   }

二,通过过滤器的方式,具体代码如下:

    @Configuration     public class GlobalCorsConfig {         @Bean         public CorsFilter corsFilter() {             CorsConfiguration config = new CorsConfiguration();             //开放哪些ip、端口、域名的访问权限,星号表示开放所有域             config.addAllowedOrigin("*");             //是否允许发送Cookie信息             config.setAllowCredentials(true);             //开放哪些Http方法,允许跨域访问             config.addAllowedMethod("GET","POST", "PUT", "DELETE");             //允许HTTP请求中的携带哪些Header信息             config.addAllowedHeader("*");             //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置             UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();             configSource.registerCorsConfiguration("/**", config);             return new CorsFilter(configSource);         }   }

接下来,我们对上述两种方式,存在失效情况分别描述:

方式1,可能失效的情况如下:

第一: 如果一个项目中存在多个WebMvcConfigurationSupport或者WebMvcConfigurerAdapter,可能会导致设置的允许跨域addCorsMappings不生效。

第二:如果一个项目中存在多个自定义的拦截器,执行顺序导致设置跨域失效,伪代码如下:

如上,执行顺序是从上至下的,导致业务拦截器先执行,本应该跨域拦截器在业务拦截器前执行。

 

方式2,使用过滤器的方式,我们应该知道过滤器是先与拦截器执行的。所以,这是我们就不要考虑到和拦截器冲突问题。其实,我项目中采用的就是这种方式,过滤器设置CORS允许跨域请求,拦截器处理业务代码(问题出现在拦截器中)。

出现CORS设置不生效时,程序的结构是,存在GlobalCorsConfig的设置就是方式二的设置,然后就是一个业务的拦截器,伪代码如下:

拦截器中代码也很简单,就是验证请求中的key是否合法,合法则不拦截,不合法拦截并响应,代码如下:

也就是采用response流输出的时候,调用了reset()函数,还记得最开头的时候,CORS设置可以简单的理解为对response设置请求头,或者你也会看到另外一种写法,如下:(也是对CORS设置的一种方式)

        HttpServletResponse response = (HttpServletResponse) res;         String allowedOriginsUrl = configurationUtil.getAllowedOriginsUrl();         String[] allowedOriginsUrlArr = allowedOriginsUrl.split(",");         for(String temp : allowedOriginsUrlArr){             response.setHeader("Access-Control-Allow-Origin",temp); // 允许的来源         }         response.setHeader("Access-Control-Allow-Credentials", "true"); // 是否允许证书         response.setHeader("Access-Control-Allow-Methods", "*"); // 允许的请求方式         response.setHeader("Access-Control-Max-Age", "3600"); // 预检请求的有效期         response.setHeader("Access-Control-Allow-Headers", "*");         chain.doFilter(req, res);

由此,可以更清楚的看出,其实就是response设置了头部header,来实现允许跨域请求。那上面的问题就很明显了,到过滤器的时候,设置了response的响应头允许跨域,但到了拦截器的时候,又把reponse重置了,导致设置的不生效。

 

结论:

1.采用CORS方式,设置允许跨域时,推荐filter的方式,这种方式先于拦截器执行。

2.如果遇到不生效的情况下,我们先采用一种最简单的方式来设置允许跨域,如果可行,放在你项目中不能使用,需要排查是否存在冲突问题了

3.解决跨域还有其他的多种方案(推荐采用代理nginx、网关方式)

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3